package cn.summit.config;

import cn.summit.serialization.adapter.*;
import cn.summit.serialization.httpmessage.MyGsonHttpMessageConverter;
import com.google.gson.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.gson.GsonBuilderCustomizer;
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.spring.web.json.Json;

import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;

/**
 * @author cn.summit
 * @since 2020/5/15 17:55
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Gson.class)
public class GsonConfig {
    @Bean
    public GsonBuilder gsonBuilder(List<GsonBuilderCustomizer> customizers) {
        GsonBuilder builder = new GsonBuilder();
        customizers.forEach(c -> c.customize(builder));
        // builder.
        builder.serializeNulls();
        builder.registerTypeAdapter(LocalDateTime.class, new DateTimeAdapter());
        builder.registerTypeAdapter(LocalDate.class, new DateAdapter());
        builder.registerTypeAdapter(LocalTime.class, new TimeAdapter());
        //builder.registerTypeAdapter(Long.class, new LongSerializer());
        builder.registerTypeAdapter(Long.class, new LongAdapter());
        builder.registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY);
        //     //生成不可执行的Json（多了 )]}' 这4个字符）
        //     //.generateNonExecutableJson()
        //     //禁止转义html标签
        //     .disableHtmlEscaping()
        //     //格式化输出
        //     .setPrettyPrinting();
        // customizers.forEach((c) -> c.customize(builder));

        // builder.serializeNulls();//为null是否要序列化成null
        // builder.registerTypeAdapter(String.class, new NameSerializer());
        //注册后，所有的 string 均按该注册方式
        //  builder.registerTypeAdapter(String.class, new NameAdapter());
        //序列化跳过指定字段
        //builder.addDeserializationExclusionStrategy(new CustSeri());

        builder.registerTypeAdapter(Json.class, new JsonSerializer<Json>() {

            @Override
            public JsonElement serialize(Json json, Type type, JsonSerializationContext context) {
                // final JsonParser parser = new JsonParser();
                // return parser.parse(json.value());

                return  new JsonPrimitive(json.value());
            }
        });

        return builder;
    }


    /**
     * 修改spring 序列化方式
     */
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(WebMvcConfigurer.class)
    @AutoConfigureAfter(HttpMessageConvertersAutoConfiguration.class)
    static class ConverterConfig implements WebMvcConfigurer {

        @Autowired
        private Gson gson;

        private MyGsonHttpMessageConverter customGsonHttpMessageConverter() {
            MyGsonHttpMessageConverter gsonMessageConverter = new MyGsonHttpMessageConverter();
            gsonMessageConverter.setGson(gson);
            return gsonMessageConverter;
        }

        @Override
        public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
            converters.removeIf(converter -> converter instanceof GsonHttpMessageConverter
                || converter instanceof MyGsonHttpMessageConverter);
            converters.add(3, customGsonHttpMessageConverter());
        }
    }
}
